package com.lsh.service;

import com.lsh.entity.Fastdfsfile;
import com.lsh.respsitory.FastdfsRespsitory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ：LiuShihao
 * @date ：Created in 2020/9/2 10:08 上午
 * @desc ：
 */
@Service
@Transactional
public class FileService {

    @Autowired
    FastdfsRespsitory fastdfsRespsitory;

    public List<Fastdfsfile> finfAll() {
        List<Fastdfsfile> all = fastdfsRespsitory.findAll();
        return all;
    }

    public void saveFile(Fastdfsfile fastdfsfile) {
//        fastdfsRespsitory.save(fastdfsfile);
        fastdfsRespsitory.addFile(fastdfsfile);
    }

    public String findNameByUrl(String url) {
        String nameByUrl = fastdfsRespsitory.findNameByUrl(url);
        return nameByUrl;
    }

    public void delFile(Integer fid) {
        fastdfsRespsitory.deleteById(fid);
    }

    /**
     * JPA  条件搜索
     * @param filename
     * @return
     */
    public List<Fastdfsfile> search(String filename) {
        Specification<Fastdfsfile> Specification = new Specification<Fastdfsfile>() {
            /**
             * @param root  根对象 : 要把条件封装进哪个对象  目的是将条件封装对象
             * @param criteriaQuery 封装查询的关键字:group by,order by等,其实无用!
             * @param criteriaBuilder 封装条件对象的   目的是封装条件对象
             * @return  如果直接返回null,表示不需要任何条件
             */
            @Override
            public Predicate toPredicate(Root<Fastdfsfile> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                /**
                 * like()  模糊查询
                 * equal() 直接查询
                 * ------------------------
                 * root.get("labelname").as(String.class)
                 * 从封装的条件对象中获得要查询的字段,该字段是String类型
                 * 参数2 : 具体查询的条件
                 * 即整体的结果就相当于是
                 *  where labelname like "%张三%"
                 *  ------------------------
                 * 如果还有需要查询的条件就再来一个criteriaBuilder.like(...);
                 * 但是该criteriaBuilder.like()返回值是Predicate对象,正是toPredicate的返回值
                 * 如果多个criteriaBuilderlike()就会返回多个Predicate对象,那该如何返回?
                 * -------------------------
                 * criteriaBuilder提供了and(Predicate... p)方法,该方法返回值是Predicate对象
                 * and()方法的参数是Predicate类型的数组,即有多少查询条件就可以使用criteriaBuilder得当多少
                 * Predicate对象,然后放入Predicate类型的数组,再放入and()返回.
                 * 但是不确定有多少查询条件啊?即不确定该Predicate类型的数组的长度啊?
                 * -------------------------
                 * 使用集合存储.集合存储所有criteriaBuilder得当的Predicate对象,然后获得集合长度,利用该长度
                 * 创建数组,然后将该集合中的值传入数组,然后将数组放入and(),最终返回
                 * -------------------------
                 * and() 就好比 where name like "%张三%" and age = 1
                 */
                List<Predicate> list = new ArrayList<>();
                root.get("name").as(String.class);
                if(filename != null && !"".equals(filename) && !"null".equals(filename)) {
                    Predicate predicate = criteriaBuilder.like(root.get("name").as(String.class), "%" + filename + "%");
                    list.add(predicate);
                }
                Predicate[] predicates = list.toArray(new Predicate[list.size()]);
                return criteriaBuilder.and(predicates);
            }
        };
        List<Fastdfsfile> all = fastdfsRespsitory.findAll(Specification);
        return all;
    }

    /**
     * JPA 条件+分页 查询
     * @param searchname
     * @param pageNum
     * @param pegeSize
     * @return
     *
     */
    public Page searchAndPage(String searchname, int pageNum, int pegeSize) {
        // Pageable是接口,PageRequest是其子类
        // jpa的第一页要设置为 0
        Pageable pageable = PageRequest.of(pageNum-1,pegeSize);
        Specification<Fastdfsfile> specification = new Specification<Fastdfsfile>() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                List<Predicate> list = new ArrayList<>();
                root.get("name").as(String.class);
                if(searchname != null && !"".equals(searchname)&& !"null".equals(searchname)) {
                    Predicate predicate = criteriaBuilder.like(root.get("name").as(String.class), "%" + searchname + "%");
                    list.add(predicate);
                }
                Predicate[] predicates = list.toArray(new Predicate[list.size()]);
                return criteriaBuilder.and(predicates);
            }
        };
        Page<Fastdfsfile> page = fastdfsRespsitory.findAll(specification, pageable);
        return page;
    }
}
